package model

import (
	"encoding/json"
)

type Post struct {
	Id          int64    `json:"id"`
	UserId      int64    `json:"user_id"`
	Type        int64    `json:"type"`
	Title       string   `json:"title"`
	Content     string   `json:"content"`  // 内容
	Cover       string   `json:"cover"`    // 封面
	FileIds     []string `json:"file_ids"` // 上传阿里云盘的文件id
	Description string   `json:"description"`
	Tags        []string `json:"tags"`
	CreatedTime string   `json:"created_time"`
	UpdatedTime string   `json:"updated_time"`
	DeletedTime *string  `json:"deleted_time"`
	Status      int64    `json:"status"`
}

type NormalSearch struct {
	Size  int64 `json:"size,omitempty"`
	From  int64 `json:"from,omitempty"`
	Query struct {
		Bool struct {
			Must []map[string]interface{} `json:"must,omitempty"`
		} `json:"bool"`
	} `json:"query,omitempty"`
	Sort []map[string]interface{} `json:"sort,omitempty"`
	Aggs map[string]interface{}   `json:"aggs,omitempty"`
}

type SearchBuilder struct {
	QuerySize         int64
	From              int64
	SimpleQueryString []map[string]interface{}
	Must              []map[string]interface{}
	Sort              []map[string]interface{}
	Aggregations      map[string]interface{}
	QueryString       string
}

func InitBuilder() *SearchBuilder {
	return &SearchBuilder{
		QuerySize:    10,
		From:         0,
		Aggregations: make(map[string]interface{}),
	}
}

func (s *SearchBuilder) SetSize(size int64) *SearchBuilder {
	if size < 1 {
		size = 10
	}
	s.QuerySize = size
	return s
}

func (s *SearchBuilder) SetPage(from int64) *SearchBuilder {
	if from < 1 || s.QuerySize*from > 10000 {
		from = 0
	}
	s.From = s.QuerySize * from
	return s
}

func (s *SearchBuilder) SetSimpleQueryString(keyword string, field []string) *SearchBuilder {
	if len(keyword) > 0 {
		s.SimpleQueryString = append(s.SimpleQueryString, map[string]interface{}{"simple_query_string": map[string]interface{}{"query": keyword, "fields": field}})
	}
	return s
}

func (s *SearchBuilder) SetMust(must []map[string]interface{}) *SearchBuilder {
	if len(must) > 0 {
		s.Must = append(s.Must, must...)
	}
	return s
}

func (s *SearchBuilder) SetSort(sort []map[string]string) *SearchBuilder {
	if len(sort) > 0 {
		for _, v := range sort {
			for k1, v1 := range v {
				s.Sort = append(s.Sort, map[string]interface{}{k1: map[string]string{"order": v1}})
			}
		}
	}
	return s
}

func (s *SearchBuilder) SetAgg(aggsTitle string, agg map[string]interface{}) *SearchBuilder {
	if len(agg) > 0 && aggsTitle != "" {
		s.Aggregations[aggsTitle] = agg
	}
	return s
}

func (s *SearchBuilder) Build() (string, error) {
	var search NormalSearch
	search.Size = s.QuerySize
	search.From = s.From
	search.Query.Bool.Must = append(search.Query.Bool.Must, s.SimpleQueryString...)
	search.Query.Bool.Must = append(search.Query.Bool.Must, s.Must...)
	search.Sort = append(search.Sort, s.Sort...)
	search.Aggs = s.Aggregations
	query, err := json.Marshal(search)
	if err != nil {
		return "", err
	}
	return string(query), nil
}
